// test_proc_1553B_CMD.c

#include <string.h>
#include "unity.h"
#include "mock_main.h"
#include "proc_1553B_CMD.h"

// test_proc_1553B_CMD.c
// Test variables
static B1553_BusService testBusServ;
static Eth_Service testEthServ;

void setUp(void)
{
    // Set up before each test
    memset(&testBusServ, 0, sizeof(B1553_BusService));
    memset(&testEthServ, 0, sizeof(Eth_Service));
}

void tearDown(void)
{
    // Clean up after each test
}

// Test cases

void test_proc_1553B_CMD_Should_HandleAltPosData(void)
{
    // Arrange
    u8 testData[B1553_BCST_POSALT_DATALEN] = {0};
    u32 testDataLen = 0;

    // First call returns CMDHANDLE_ALTPOS
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &testDataLen, CMDHANDLE_ALTPOS);
    eth_store_AltPos_data_Expect(testData, testDataLen);

    // Second call returns 0 to exit loop
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &testDataLen, 0);

    // Act
    proc_1553B_CMD(&testBusServ, &testEthServ);

    // Assert - handled by CMock expectations
}

void test_proc_1553B_CMD_Should_HandleTimeData(void)
{
    // Arrange
    u8 testData[B1553_BCST_POSALT_DATALEN] = {0};
    u32 testDataLen = 0; // Arbitrary length for time data

    // First call returns CMDHANDLE_TIME
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &testDataLen, CMDHANDLE_TIME);
    eth_store_bcst_time_Expect(&testEthServ, (u16 *)testData, testDataLen);
    idleTestMode_getTM_Expect();

    // Second call returns 0 to exit loop
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &testDataLen, 0);

    // Act
    proc_1553B_CMD(&testBusServ, &testEthServ);

    // Assert - handled by CMock expectations
}

void test_proc_1553B_CMD_Should_HandleSamplePeriodDataInjection(void)
{
    // Arrange
    u8 testData[B1553_BCST_POSALT_DATALEN] = {0};
    u32 testDataLen = sizeof(struct BusCmdData);
    u32 ret_testDataLen = 0;
    struct BusCmdData *cmdData = (struct BusCmdData *)testData;
    cmdData->funcID = DATAINJ_SAMPLE_PERIOD;
    cmdData->data[0] = 1000; // Sample period value

    // memcpy(testData, cmdData, sizeof(struct BusCmdData));

    // First call returns CMDHANDLE_DATAINJ
    // B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &testDataLen, CMDHANDLE_DATAINJ);
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, 0, &ret_testDataLen, CMDHANDLE_DATAINJ);
    B1553_CMDHandle_IgnoreArg_pRetData();
    B1553_CMDHandle_ReturnThruPtr_pRetData(cmdData);

    t_memcpy_Expect(NULL, testData, testDataLen);
    t_memcpy_IgnoreArg_pcmd();
    t_memcpy_ReturnThruPtr_pcmd(cmdData);

    timer_kl202_setRstValue_Expect(1000);

    // Second call returns 0 to exit loop
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &ret_testDataLen, 0);

    // Act
    proc_1553B_CMD(&testBusServ, &testEthServ);

    // Assert - handled by CMock expectations
}

void test_proc_1553B_CMD_Should_HandleIPConfigDataInjection(void)
{
    // Arrange
    u8 testData[B1553_BCST_POSALT_DATALEN] = {0};
    u32 testDataLen = sizeof(struct BusCmdData);
    u32 ret_testDataLen = 0;
    struct BusCmdData *cmdData = (struct BusCmdData *)testData;
    cmdData->funcID = DATAINJ_IP_CFG;

    // Fill with test data for IP/MAC configuration
    for (int i = 0; i < 4; i++)
    {
        cmdData->data[i] = 192 + i; // IP address bytes
    }
    cmdData->data[11] = 80; // Port number

    for (int i = 0; i < 8; i++)
    {
        cmdData->data[i + 8] = 0xAA + i; // MAC address bytes
    }

    // First call returns CMDHANDLE_DATAINJ
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &ret_testDataLen, CMDHANDLE_DATAINJ);
    B1553_CMDHandle_IgnoreArg_pRetData();
    B1553_CMDHandle_ReturnThruPtr_pRetData(cmdData);

    t_memcpy_Expect(NULL, testData, testDataLen);
    t_memcpy_IgnoreArg_pcmd();
    t_memcpy_ReturnThruPtr_pcmd(cmdData);

    eth_modify_MAC_IP_Port_Expect(&testEthServ, &(cmdData->data[8]), &(cmdData->data[0]), cmdData->data[11]);

    // Second call returns 0 to exit loop
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &ret_testDataLen, 0);

    // Act
    proc_1553B_CMD(&testBusServ, &testEthServ);

    // Assert - handled by CMock expectations
    TEST_ASSERT_EQUAL(cmdData->data[0], 192);
}

void test_proc_1553B_CMD_Should_HandleCloudThresholdDataInjection(void)
{
    // Arrange
    u8 testData[B1553_BCST_POSALT_DATALEN] = {0};
    u32 testDataLen = sizeof(struct BusCmdData);
    u32 ret_testDataLen = 0;
    struct BusCmdData *cmdData = (struct BusCmdData *)testData;
    cmdData->funcID = DATAINJ_CLOUD_THREHOLD;
    cmdData->data[0] = 50; // Threshold value

    // First call returns CMDHANDLE_DATAINJ
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &ret_testDataLen, CMDHANDLE_DATAINJ);
    B1553_CMDHandle_IgnoreArg_pRetData();
    B1553_CMDHandle_ReturnThruPtr_pRetData(cmdData);

    t_memcpy_Expect(NULL, testData, testDataLen);
    t_memcpy_IgnoreArg_pcmd();
    t_memcpy_ReturnThruPtr_pcmd(cmdData);

    eth_modify_cloud_threshold_Expect(50);

    // Second call returns 0 to exit loop
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &ret_testDataLen, 0);

    // Act
    proc_1553B_CMD(&testBusServ, &testEthServ);

    // Assert - handled by CMock expectations
}

void test_proc_1553B_CMD_Should_HandleCalibrationParameterDataInjection(void)
{
    // Arrange
    u8 testData[B1553_BCST_POSALT_DATALEN] = {0};
    u32 testDataLen = sizeof(struct BusCmdData);
    u32 ret_testDataLen = 0;
    struct BusCmdData *cmdData = (struct BusCmdData *)testData;
    cmdData->funcID = DATAINJ_CALIBRATION_PARA;

    // First call returns CMDHANDLE_DATAINJ
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &ret_testDataLen, CMDHANDLE_DATAINJ);
    B1553_CMDHandle_IgnoreArg_pRetData();
    B1553_CMDHandle_ReturnThruPtr_pRetData(cmdData);

    t_memcpy_Expect(NULL, testData, testDataLen);
    t_memcpy_IgnoreArg_pcmd();
    t_memcpy_ReturnThruPtr_pcmd(cmdData);

    // Second call returns 0 to exit loop
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &ret_testDataLen, 0);

    // Act
    proc_1553B_CMD(&testBusServ, &testEthServ);

    // Assert - handled by CMock expectations
}

void test_proc_1553B_CMD_Should_HandleFlashEraseDataInjection(void)
{
    // Arrange
    u8 testData[B1553_BCST_POSALT_DATALEN] = {0};
    u32 testDataLen = sizeof(struct BusCmdData);
    u32 ret_testDataLen = 0;
    struct BusCmdData *cmdData = (struct BusCmdData *)testData;
    cmdData->funcID = DATAINJ_FLASH_ERASE;

    // Fill with test data
    for (int i = 0; i < 32; i++)
    {
        cmdData->data[i] = i;
    }

    // First call returns CMDHANDLE_DATAINJ
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &ret_testDataLen, CMDHANDLE_DATAINJ);
    B1553_CMDHandle_IgnoreArg_pRetData();
    B1553_CMDHandle_ReturnThruPtr_pRetData(cmdData);

    t_memcpy_Expect(NULL, testData, testDataLen);
    t_memcpy_IgnoreArg_pcmd();
    t_memcpy_ReturnThruPtr_pcmd(cmdData);

    uart_rs01_send_Expect(&(cmdData->data[0]), 32);
    dbg_print_Expect(&(cmdData->data[0]), 32);
    uart_rs01_rcvTM_Expect();

    // Second call returns 0 to exit loop
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &ret_testDataLen, 0);

    // Act
    proc_1553B_CMD(&testBusServ, &testEthServ);

    // Assert - handled by CMock expectations
}

void test_proc_1553B_CMD_Should_HandleIdleModeBusCommand(void)
{
    // Arrange
    u8 testData[B1553_BCST_POSALT_DATALEN] = {0};
    u32 testDataLen = sizeof(struct BusCmdData);
    u32 ret_testDataLen = 0;
    struct BusCmdData *cmdData = (struct BusCmdData *)testData;
    cmdData->paraID1 = SYS_MODE_IDLE;

    // First call returns CMDHANDLE_BUSCMD
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &ret_testDataLen, CMDHANDLE_BUSCMD);
    B1553_CMDHandle_IgnoreArg_pRetData();
    B1553_CMDHandle_ReturnThruPtr_pRetData(cmdData);

    t_memcpy_Expect(NULL, testData, testDataLen);
    t_memcpy_IgnoreArg_pcmd();
    t_memcpy_ReturnThruPtr_pcmd(cmdData);

    timer_kl202_stop_Expect();

    // Second call returns 0 to exit loop
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &ret_testDataLen, 0);

    // Act
    proc_1553B_CMD(&testBusServ, &testEthServ);

    // Assert - handled by CMock expectations
}

void test_proc_1553B_CMD_Should_HandleWorkModeBusCommand(void)
{
    // Arrange
    u8 testData[B1553_BCST_POSALT_DATALEN] = {0};
    u32 testDataLen = sizeof(struct BusCmdData);
    u32 ret_testDataLen = 0;
    struct BusCmdData* cmdData = (struct BusCmdData*)testData;
    cmdData->paraID1 = SYS_MODE_WORK;

    // First call returns CMDHANDLE_BUSCMD
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &ret_testDataLen, CMDHANDLE_BUSCMD);
    B1553_CMDHandle_IgnoreArg_pRetData();
    B1553_CMDHandle_ReturnThruPtr_pRetData(cmdData);

    t_memcpy_Expect(NULL, testData, testDataLen);
    t_memcpy_IgnoreArg_pcmd();
    t_memcpy_ReturnThruPtr_pcmd(cmdData);

    timer_capture_gettime_Expect(NULL, 2);
    timer_capture_gettime_IgnoreArg_current_time();
    u32 foo_time[2] = {12345, 67890};
    timer_capture_gettime_ReturnThruPtr_current_time(foo_time);


    eth_store_subSecond_time_Expect(&testEthServ, NULL, 2);
    eth_store_subSecond_time_IgnoreArg_ptr();

    timer_kl202_start_Expect();
    uart_start_acquire_Expect();
    B1553_TMadd_Comm_RS422_TX_Count_Expect(&testBusServ);

    // Second call returns 0 to exit loop
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &ret_testDataLen, 0);

    // Act
    proc_1553B_CMD(&testBusServ, &testEthServ);

    // Assert - handled by CMock expectations
}

void test_proc_1553B_CMD_Should_HandleUnknownCommandType(void)
{
    // Arrange
    u8 testData[B1553_BCST_POSALT_DATALEN] = {0};
    u32 testDataLen = 0;

    // First call returns unknown command type
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &testDataLen, 999); // Unknown command type

    // Second call returns 0 to exit loop
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData, &testDataLen, 0);

    // Act
    proc_1553B_CMD(&testBusServ, &testEthServ);

    // Assert - handled by CMock expectations
}

void test_proc_1553B_CMD_Should_HandleMultipleCommandsInSequence(void)
{
    // Arrange
    u8 testData1[B1553_BCST_POSALT_DATALEN] = {0};
    u8 testData2[B1553_BCST_POSALT_DATALEN] = {0};
    u32 testDataLen = 100;
    u32 ret_testDataLen = 0;

    // Sequence of commands: ALTPOS -> TIME -> 0 (exit)
    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData1, &ret_testDataLen, CMDHANDLE_ALTPOS);
    // B1553_CMDHandle_IgnoreArg_pRetData();
    // B1553_CMDHandle_ReturnThruPtr_pRetData(cmdData);
    eth_store_AltPos_data_Expect(testData1, ret_testDataLen);

    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData2, &ret_testDataLen, CMDHANDLE_TIME);
    
    eth_store_bcst_time_Expect(&testEthServ, (u16*)testData2, ret_testDataLen);
    idleTestMode_getTM_Expect();

    B1553_CMDHandle_ExpectAndReturn(&testBusServ, testData2, &ret_testDataLen, 0);

    // Act
    proc_1553B_CMD(&testBusServ, &testEthServ);

    // Assert - handled by CMock expectations
}